//SPDX-License-Identifier:	GPL-2.0+

#ifndef __LS3A_COMMON_H
#define __LS3A_COMMON_H

#include <linux/sizes.h>

/* Loongson bootelf bootparam smbios */
#define CONFIG_LOONGSON_BOOT_FIXUP
#ifdef CONFIG_CPU_LOONGSON3A4000
#define CONFIG_SMBIOS_PRODUCT_NAME "Loongson 3A4000"
#endif
#ifdef CONFIG_CPU_LOONGSON3A3000
#define CONFIG_SMBIOS_PRODUCT_NAME "Loongson 3A3000"
#endif
#define CONFIG_SMBIOS_MANUFACTURER "Loongson"

#define LS7A_SYS_CLK      100000000 //LS7A1000使用外部参考时钟100MHz（固定）

#ifdef CONFIG_CPU_LOONGSON3A4000
#define CPUPLL_IN         100000000
#define DDRPLL_IN         100000000
#define BUSPLL_IN         100000000

#define CPU_CLOCK_RATE    1800000000
#define DDR_CLOCK_RATE    533000000
#endif
#ifdef CONFIG_CPU_LOONGSON3A3000
#define CPUPLL_IN         25000000
#define DDRPLL_IN         33000000
//#define BUSPLL_IN         33000000
#define BUSPLL_IN         33333333

#define CPU_CLOCK_RATE    1400000000
#define DDR_CLOCK_RATE    429000000
#endif

#define CPU_TCLOCK_RATE CPU_CLOCK_RATE
#define CONFIG_SYS_MIPS_TIMER_FREQ  (CPU_TCLOCK_RATE / 2)
#define CONFIG_SYS_HZ   1000

/* memory */
#ifdef CONFIG_32BIT
#define CONFIG_SYS_SDRAM_BASE		0x80000000	/* Cached addr */
#define CONFIG_SYS_INIT_SP_OFFSET	0x00400000
#define CONFIG_SYS_LOAD_ADDR		0x83000000
#define FDT_LOAD_ADDR		0x8b000000
#define FDT_MULTI_ADDR	0x8b020000
#define RAMDISK_START		0x88000000
#define RAMDISK_SIZE		0x02000000
#endif
#ifdef CONFIG_64BIT
#define CONFIG_SYS_SDRAM_BASE		0xffffffff80000000	/* Cached addr */
#define CONFIG_SYS_INIT_SP_OFFSET	0x0000000000400000
#define CONFIG_SYS_LOAD_ADDR		0xffffffff83000000
#define FDT_LOAD_ADDR		0xffffffff8b000000
#define FDT_MULTI_ADDR	0xffffffff8b020000
#define RAMDISK_START		0xffffffff88000000
#define RAMDISK_SIZE		0x02000000
#define CONFIG_ARCH_MAP_SYSMEM
#endif

/* DMA */
//#define CONFIG_DMA_COHERENT
//#define CONFIG_DMA_COHERENT_SIZE	(1 << 20)

/* Miscellaneous configurable options */
#define CONFIG_SYS_MAXARGS 64	/* max number of command args */
#define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */

#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE
//#define CONFIG_SYS_MONITOR_LEN		(192 << 10)
#define CONFIG_SYS_MALLOC_LEN	(28 * 1024 * 1024)

/* 串口打印信息，汇编调试 */
#define CONFIG_PRINTK
#ifndef CONFIG_DM_SERIAL
#define CONFIG_CPU_UART
#define CONFIG_CONS_INDEX	1
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE	 1
#endif
#define CONFIG_SYS_NS16550_CLK	BUSPLL_IN
#define CONFIG_SYS_NS16550_COM1	 CKSEG1ADDR(0x1fe001e0)
#define UART_BASE_ADDR	CONFIG_SYS_NS16550_COM1

/* LS1X SPI Settings */
#ifdef CONFIG_LS1X_SPI
//#define CONFIG_LS1X_SPI1_ENABLE	/* 使用spi1控制器(复用设置), spi1控制器复用can，如果不使用spi1，最好把该选项关闭 */
#define CONFIG_SPI_CS
//#define CONFIG_SPI_CS_USED_GPIO
#endif

/* Environment settings */
#define CONFIG_ENV_SIZE			0x4000	/* 16KB */
#define CONFIG_ENV_OVERWRITE
#if defined(CONFIG_ENV_IS_IN_NVRAM)
#define CONFIG_ENV_ADDR		0x9fc40000
#elif defined(CONFIG_ENV_IS_IN_FLASH)
#define CONFIG_SYS_FLASH_BASE  0x9fc00000
#define CONFIG_ENV_ADDR			(CONFIG_SYS_FLASH_BASE + 0x100000)
//#define CONFIG_ENV_SECT_SIZE		0x20000
#define CONFIG_ENV_SECT_SIZE	(4 << 10)
//#define CONFIG_ENV_SIZE			0x20000
#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
#define CONFIG_ENV_SPI_CS		0
#define CONFIG_ENV_SPI_MAX_HZ	30000000
#define CONFIG_ENV_OFFSET		0x140000	/* 根据分区大小修改，这里是SPI Flash uboot_env0的偏移地址 */
#define CONFIG_ENV_SECT_SIZE	(4 << 10)
#endif
/*
 * Environment is right behind U-Boot in flash. Make sure U-Boot
 * doesn't grow into the environment area.
 */
#define CONFIG_BOARD_SIZE_LIMIT		CONFIG_ENV_OFFSET

/* PCI */
#ifdef  CONFIG_PCIE_LOONGSON2_SOC
//#define CONFIG_PCI_CONFIG_HOST_BRIDGE
#define CONFIG_PCI_SCAN_SHOW
#endif

#if defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO)
#define VIDEO_FB_16BPP_WORD_SWAP
#define CONFIG_SPLASH_SCREEN
#define CONFIG_SPLASH_SCREEN_ALIGN
/* logo 设置 */
#define CONFIG_VIDEO_LOGO
#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_VIDEO_BMP_LOGO
#define CONFIG_BMP_16BPP
#define CONFIG_BMP_24BPP
#define CONFIG_BMP_32BPP
#endif
#ifdef CONFIG_VIDEO_VESA
#define CONFIG_BIOSEMU
#define VIDEO_IO_OFFSET CKSEG1ADDR(0x18000000)
#endif

/* SCSI */
#if defined(CONFIG_SCSI_AHCI) && !defined(CONFIG_DM_SCSI)
#define SCSI_VEND_ID 0x0014
#define SCSI_DEV_ID  0x7a08
#define CONFIG_SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
#if !defined(CONFIG_PCI)
#define CONFIG_SCSI_AHCI_PLAT
#endif
#define CONFIG_SYS_SCSI_MAX_SCSI_ID	1
#define CONFIG_SYS_SCSI_MAX_LUN	1
#define CONFIG_SYS_SCSI_MAX_DEVICE	(CONFIG_SYS_SCSI_MAX_SCSI_ID * CONFIG_SYS_SCSI_MAX_LUN)
#endif

/* USB */
#ifdef CONFIG_USB_OHCI_HCD
#define CONFIG_USB_OHCI_NEW
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	8
#endif

/* Ethernet driver configuration */
#if defined(CONFIG_LOONGSON_GMAC) || defined(CONFIG_ETH_DESIGNWARE)
#define ENH_DESC //ls2x的gmac控制器需要把该宏定义打开
#define CONFIG_DW_GMAC_DEFAULT_DMA_PBL 4
#define CONFIG_DW_ALTDESCRIPTOR
#define PHY_ANEG_TIMEOUT	8000
#endif
#define CONFIG_NET_MULTI
#define CONFIG_NET_RETRY_COUNT          5

#define CONFIG_ETHADDR		08:00:3e:26:0a:5b
#define CONFIG_IPADDR		192.168.1.20
#define CONFIG_NETMASK		255.255.255.0
#define CONFIG_SERVERIP		192.168.1.2

#ifdef CONFIG_VIDEO
#define CONSOLE_STDOUT_SETTINGS \
	"stdin=serial,usbkbd\0" \
	"stdout=serial\0" \
	"stderr=serial,vga\0"
#elif CONFIG_DM_VIDEO
#define CONSOLE_STDOUT_SETTINGS \
	"splashimage=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
	"stdin=serial,usbkbd\0" \
	"stdout=serial\0" \
	"stderr=serial,vidconsole,vidconsole1,vidconsole2\0"
#else
#define CONSOLE_STDOUT_SETTINGS \
	"stdin=serial\0" \
	"stdout=serial\0" \
	"stderr=serial\0"
#endif

#ifdef CONFIG_RECOVER
#define RECOVER_DEFAULT_ENV setenv bootargs console=ttyS0,115200 rd_start=${rd_start} rd_size=${rd_size} \
mtdparts=${mtdparts} \
root=/dev/ram rw rootfstype=ext2 \
video=${video};\
bootm ${loadaddr}

#define RECOVER_USB_DEFAULT "usb start;fatload usb 0:1 ${loadaddr} /install/uImage;fatload usb 0:1 ${rd_start} /install/ramdisk.gz;\
" __stringify(RECOVER_DEFAULT_ENV) ""
#endif //CONFIG_RECOVER

#define BOOT_SATA_DEFAULT "setenv bootargs console=ttyS0,115200 \
rootfstype=ext4 rw rootwait; \
setenv bootcmd ' setenv bootargs ${bootargs} root=/dev/${root_dev}${rootpart} mtdparts=${mtdparts} video=${video}; \
sf probe;sf read ${fdt_addr} dtb;scsi scan;ext4load scsi 0:${syspart} ${loadaddr} /boot/uImage;bootm ';\
saveenv;\
boot"

#define BOOT_USB_DEFAULT "setenv bootargs console=ttyS0,115200 \
rootfstype=ext4 rw rootwait; \
setenv bootcmd ' setenv bootargs ${bootargs} root=/dev/${root_dev}${rootpart} mtdparts=${mtdparts} video=${video}; \
sf probe;sf read ${fdt_addr} dtb;usb start;ext4load usb 0:${syspart} ${loadaddr} /boot/uImage;bootm ';\
saveenv;\
boot"

#define CONFIG_SYS_BOOTM_LEN	SZ_64M

/* ls3x ddr配置 */
#ifdef CONFIG_CPU_LOONGSON3A4000
#define LOONGSON3A4000
#define LS3A4000
#define loongson3A3

#define USE_DBL

//#define DDR3_DIMM
#define LSMC_2
#define DDR_FREQ (DDR_CLOCK_RATE / 1000000)
#define ENABLE_MC_VREF_TRAINING
#define VREF_STORE

#define LS3_HT
#define LOONGSON_3ASINGLE
#define LS7A

#define BONITO_100M
#define RESERVED_COREMASK 0xfff0
#define SHUTDOWN_MASK 0x0000
#define BOOTCORE_ID 0

#define AUTO_DDR_CONFIG
#define USE_LS2H_I2C

//#define LS132_CORE

#define CPU_FREQ  CPU_CLOCK_RATE
#define CORE_FREQ CPU_CLOCK_RATE
#define SYS_CLOCK 100 //MUST BE 100 or 25, depend on the osillator

/* DDR_PARAM访问地址使用SPI memory地址，
SPI memory地址映射范围16MB，SPI boot地址映射范围只有1MB
当DDR_PARAM_OFFSET的地址大于1MB时，如果使用SPI boot地址，则访问失败
 */
#define DDR_PARAM_OFFSET 0x00166000	/* 根据分区大小修改，这里是SPI Flash ddr_param的偏移地址 */
#define LOCK_SCACHE_ADDR 0x90000000
/*
 * -----------------------------------------------------------------------------------------------
 * | CLK0:8 | SLOT0_SPD0:8 | SLOT1_SPD0:8 | VREF0:12 | BIT_TRAIN0:252 | DDR_VREF0:8 | DBL_CFG0:1 |
 * | CLK1:8 | SLOT0_SPD1:8 | SLOT0_SPD1:8 | VREF1:12 | BIT_TRAIN1:252 | DDR_VREF1:8 | DBL_CFG1:1 |
 * -----------------------------------------------------------------------------------------------
 */
#define DIMM_INFO_IN_FLASH_OFFS  (0xffffffff9d000000 + DDR_PARAM_OFFSET)
#define DIMM_INFO_IN_CACHE_OFFS  (0x9800000000000000 | LOCK_SCACHE_ADDR)
#define MC_PARAM_IN_CACHE_OFFS   (0x9800000000008000 | LOCK_SCACHE_ADDR)
#define DIMM_SPD_STORED_OFFS     0x4000
#define DDR_TRAIN_FLAG_OFFS      0x2000
#define SLOT0_SPD_OFFS           0x2008
#define LOCK_SCACHE_MASK         0xffffffffffff0000
#ifdef CONFIG_32BIT
#define DIMM_INFO_IN_SDRAM_OFFS  0x8fff0000
#endif
#ifdef CONFIG_64BIT
#define DIMM_INFO_IN_SDRAM_OFFS  0xffffffff8fff0000
#endif
#define DIMM_OFFS_CLK		0
#define DIMM_OFFS_SLOT0_SPD 8
#define DIMM_OFFS_SLOT1_SPD 16
#define DIMM_OFFS_VREF		24
#define DIMM_OFFS_BIT_TRAIN 36
#define DIMM_OFFS_DDR_VREF  288
#define DIMM_OFFS_DBL_CFG   296
#define DBL_DCC_TRAIN_OFFS  0xc00

#define DIMM_INFO_SIZE		608
#define MC_INFO_SIZE		304
#define DIMM_VREF_DATA_NUM	9	/* vref has used 9 byte */
#define DIMM_OFFS_SPD1		(MC_INFO_SIZE + DIMM_OFFS_SPD)

#ifndef AUTO_DDR_CONFIG
#define S1_VALUE \
(0x0   << S1_CID_NUM_OFFSET_V1     )|\
(0x2   << S1_BG_NUM_OFFSET_V1      )|\
(0x0   << S1_BA_NUM_OFFSET_V1      )|\
(0x2   << S1_ROW_SIZE_OFFSET_V1    )|\
(0x2   << S1_COL_SIZE_OFFSET_V1    )|\
(0x0   << S1_ADDR_MIRROR_OFFSET_V1 )|\
(0x8   << S1_DIMM_MEMSIZE_OFFSET_V1)|\
(0x3   << S1_DIMM_WIDTH_OFFSET_V1  )|\
(0x0   << S1_DIMM_ECC_OFFSET_V1    )|\
(0x0   << S1_DIMM_TYPE_OFFSET_V1   )|\
(0x1   << S1_SDRAM_WIDTH_OFFSET_V1 )|\
(0x4   << S1_SDRAM_TYPE_OFFSET_V1  )|\
(0x1   << S1_MC_CS_MAP_OFFSET_V1   )|\
(0x1   << S1_I2C_ADDR_OFFSET_V1    )

#define S3_VALUE \
(0x0   << S1_CID_NUM_OFFSET_V1     )|\
(0x2   << S1_BG_NUM_OFFSET_V1      )|\
(0x0   << S1_BA_NUM_OFFSET_V1      )|\
(0x2   << S1_ROW_SIZE_OFFSET_V1    )|\
(0x2   << S1_COL_SIZE_OFFSET_V1    )|\
(0x0   << S1_ADDR_MIRROR_OFFSET_V1 )|\
(0x8   << S1_DIMM_MEMSIZE_OFFSET_V1)|\
(0x3   << S1_DIMM_WIDTH_OFFSET_V1  )|\
(0x0   << S1_DIMM_ECC_OFFSET_V1    )|\
(0x0   << S1_DIMM_TYPE_OFFSET_V1   )|\
(0x1   << S1_SDRAM_WIDTH_OFFSET_V1 )|\
(0x4   << S1_SDRAM_TYPE_OFFSET_V1  )|\
(0x1   << S1_MC_CS_MAP_OFFSET_V1   )|\
(0x2   << S1_I2C_ADDR_OFFSET_V1    )
#endif

#endif //CONFIG_CPU_LOONGSON3A4000

#ifdef CONFIG_CPU_LOONGSON3A3000

#endif

#endif	/* __LS3A_COMMON_H */